ng911ok.lib.topology module#

Implements functionality related to topology.yml. Exposes topology_config, which contains the data derived from topology.yml``.

Provides constructors for the following YAML tags (on yaml.SafeLoader):

  • !FieldRole (Scalar -> NG911Field) - Given a field’s role, returns the corresponding field object

  • !DomainName (Scalar -> NG911Domain) - Given a domain’s name, returns the corresponding field object

final class TopologyRule(dataset: str, member1: NG911FeatureClass, rule: str, member2: NG911FeatureClass | None = None)#

Bases: object

classmethod as_df(members_as: Literal['OBJECT', 'ROLE', 'NAME'] = 'OBJECT', rule_as: Literal['DESCRIPTION', 'ETRT'] = 'DESCRIPTION') DataFrame#

Returns all registered topology rules as a DataFrame with three columns: member1, rule, and member2.

The member1 and member2 columns will have the dtype object if members_as is OBJECT or the dtype string[python] if members_as is ROLE (meaning the NG911FeatureClass.role attribute) or NAME (meaning the NG911FeatureClass.name attribute).

The rule column will have the dtype string[python].

Parameters:
  • members_as (Literal["OBJECT", "ROLE", "NAME"]) – How the member should be represented.

  • rule_as (Literal["DESCRIPTION", "ETRT"]) – How the rules should be represented.

Return pd.DataFrame:

The registered topology rules as a DataFrame.

classmethod from_dict(dataset: str, data: _OneMemberTopologyRuleDict | _TwoMemberTopologyRuleDict) Self#
add_rule_to_topology(topology_name: str, manager: EnvManager | None = None) Result#

Adds the rule to a topology using arcpy.

as_series(members_as: Literal['OBJECT', 'ROLE', 'NAME'] = 'OBJECT', rule_as: Literal['DESCRIPTION', 'ETRT'] = 'DESCRIPTION') Series#
has_member(feature_class: NG911FeatureClass) bool#

Returns whether a given feature class is a member of the rule.

_registered_rules: ClassVar[list[Self]] = [TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'discrepancyagency_boundary'>, rule='Must Not Overlap (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Have Dangles (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Intersect (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Single Part (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'address_point'>, rule='Must Be Properly Inside (Point-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Inside (Line-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esz_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>)]#
dataset: str#
member1: NG911FeatureClass#
member2: NG911FeatureClass | None#
property members: tuple[NG911FeatureClass] | tuple[NG911FeatureClass, NG911FeatureClass]#

Returns a tuple of the member or members of the rule.

property name1: str#

Returns the name of member1.

property name2: str | None#

Returns the name of member2.

rule: str#
property rule_code: str#

Returns the esriTopologyRuleType code for the rule.

class _NG911TopologyConfig(exception_field: NG911Field, exception_domain: NG911Domain, required_dataset_topology_name: str, optional_dataset_topology_name: str, required_dataset_rules: FrozenList[TopologyRule], optional_dataset_rules: FrozenList[TopologyRule])#

Bases: YAMLObject

yaml_loader#

alias of SafeLoader

classmethod from_yaml(loader: SafeLoader, node: Node)#

Convert a representation node to a Python object.

add_members_to_topology(gdb: str, *, required_ds_topology: str | None = None, optional_ds_topology: str | None = None) tuple[int, int]#

Adds all missing members to the required and/or optional datasets’ topologies.

Parameters:
  • gdb (str) – Path to the NG911 geodatabase

  • required_ds_topology (str) – Name of the topology in the required feature dataset

  • optional_ds_topology (str) – Name of the topology in the optional feature dataset

Returns:

Number of feature classes added to the required and optional datasets’ topologies, respectively

Return type:

tuple[int, int]

enrich_error_df(error_df: DataFrame, members: Collection[DataFrame], fill_na_submit: bool | None = None) DataFrame#

Processes a topology error DataFrame (from the Export Topology Errors geoprocessing tool). Unless it is empty, the returned pandas.DataFrame will have the following columns:

Column Name

dtype

OriginObjectClassName

string

OriginObjectID

Int32

DestinationObjectClassName

string

DestinationObjectID

Int32

RuleType

string

RuleDescription

string

SHAPE

geometry

OriginObjectClassObject

object

OriginObjectNGUID

string

OriginObjectSubmit

boolean

OriginObjectExceptions

object

DestinationObjectClassObject

object

DestinationObjectNGUID

string

DestinationObjectSubmit

boolean

DestinationObjectExceptions

object

RuleObject

object

IsException

boolean

Parameters:
  • error_df – Topology error DataFrame

  • members – All relevant member feature classes as DataFrames

  • fill_na_submit – Value to assume for invalid values of SUBMIT; if None, a ValueError will be raised if any features involved in an error have an invalid or missing value for that attribute; default None

Returns:

Copy of topology error DataFrame with additional columns

get_rule(member1: NG911FeatureClass | NAType | None, rule_code: esriTopologyRuleType | str, member2: NG911FeatureClass | NAType | None = None) TopologyRule | None#

Searches through the known rules for a rule matching the arguments and returns it. Returns None if no rule is found.

Parameters:
  • member1 (NG911FeatureClass | NAType | None) – Feature class representing the first member

  • rule_code (esriTopologyRuleType | str) – The string code (e.g., esriTRTLineNoDangles), the string description (e.g., “Must Not Have Dangles (Line)”), or the esriTopologyRuleType instance representing the rule

  • member2 (NG911FeatureClass | NAType | None) – Feature class representing the second member, or None (or pandas.NA, which will be treated the same as None) if not applicable; default None

Returns:

The rule matching the arguments, or None if no such rule could be found

Return type:

TopologyRule | None

_dangle_exc = frozenset({'esriTRTLineNoDangles'})#
_inside_exc = frozenset({'esriTRTLineInsideArea', 'esriTRTPointProperlyInsideArea'})#
address_point_allowed_values: ClassVar[frozenset[LiteralString]] = frozenset({'INSIDE_EXCEPTION', 'NO_EXCEPTION'})#
exception_domain: NG911Domain#
exception_field: NG911Field#
exception_mapping: ClassVar[FrozenDict[LiteralString, frozenset[str]]] = FrozenDict({'DANGLE_EXCEPTION': frozenset({'esriTRTLineNoDangles'}), 'INSIDE_EXCEPTION': frozenset({'esriTRTPointProperlyInsideArea', 'esriTRTLineInsideArea'}), 'BOTH_EXCEPTION': frozenset({'esriTRTPointProperlyInsideArea', 'esriTRTLineInsideArea', 'esriTRTLineNoDangles'}), 'NO_EXCEPTION': frozenset()})#
property optional_dataset_members: frozenset[NG911FeatureClass]#

Returns a frozenset with all NG911FeatureClass objects that are involved in self.optional_dataset_rules.

optional_dataset_rules: FrozenList[TopologyRule]#
optional_dataset_topology_name: str#
property required_dataset_members: frozenset[NG911FeatureClass]#

Returns a frozenset with all NG911FeatureClass objects that are involved in self.required_dataset_rules.

required_dataset_rules: FrozenList[TopologyRule]#
required_dataset_topology_name: str#
yaml_tag = '!TopologyConfig'#
class _OneMemberTopologyRuleDict#

Bases: TypedDict

member: str#
rule: str#
class _TopologyConfigDict#

Bases: TypedDict

exception_domain: NG911Domain#
exception_field: NG911Field#
optional_dataset_rules: NotRequired[list[_OneMemberTopologyRuleDict | _TwoMemberTopologyRuleDict]]#
optional_dataset_topology_name: str#
required_dataset_rules: list[_OneMemberTopologyRuleDict | _TwoMemberTopologyRuleDict]#
required_dataset_topology_name: str#
class _TwoMemberTopologyRuleDict#

Bases: TypedDict

member1: str#
member2: str#
rule: str#
_construct_domain_from_name(loader: SafeLoader, node: Node) NG911Domain#
_construct_field_from_role(loader: SafeLoader, node: Node) NG911Field#
topology_config: _NG911TopologyConfig = _NG911TopologyConfig(exception_field=NG911Field(role='topoexcept', name='TopoExcept', type='String', priority='M', length=20, domain=<NG911Domain 'TOPOEXCEPT' [4 Entries]>, fill_value='NO_EXCEPTION'), exception_domain=<NG911Domain 'TOPOEXCEPT' [4 Entries]>, required_dataset_topology_name='NG911_Topology', optional_dataset_topology_name='OptionalLayers_Topology', required_dataset_rules=FrozenList((TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'discrepancyagency_boundary'>, rule='Must Not Overlap (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Have Dangles (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Intersect (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Single Part (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'address_point'>, rule='Must Be Properly Inside (Point-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Inside (Line-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esz_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>))), optional_dataset_rules=FrozenList(()))#

The single instance of _NG911TopologyConfig that contains the topology rules specified in topology.yml.